/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.appspot.trick.it.admin.controller;

import com.appspot.trick.it.admin.TrickAdmin;
import com.appspot.trick.it.admin.bind.ArticleTreeProgressVisibleBinding;
import com.appspot.trick.it.admin.custom.ArticleTreeItem;
import com.appspot.trick.it.admin.db.DBManager;
import com.appspot.trick.it.admin.db.SiteMstEntity;
import com.appspot.trick.it.admin.model.ArticleModel;
import com.appspot.trick.it.admin.task.ArticleAddTask;
import com.appspot.trick.it.admin.task.ArticleChangeIndexTask;
import com.appspot.trick.it.admin.task.ArticleDeleteTask;
import com.appspot.trick.it.admin.task.ArticleLoadListTask;
import com.appspot.trick.it.admin.task.ArticleUpdateTitleTask;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.List;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TreeView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;

/**
 *
 * @author takahara
 */
public class MainController extends AnchorPane implements Initializable {
    
    /**
     * MainController instance
     */
    private static MainController instance;
    
    /**
     * アカウントチョイスボックス
     */
    @FXML
    private ChoiceBox<SiteMstEntity> accountChoiceBox;
    /**
     * プログレスBOX
     */
    @FXML
    private HBox treeProgressIndicatorHBox;

    /**
     * アカウント情報
     */
    private SiteMstEntity siteMstEntity;
    
    /**
     * タスク
     */
    private final ArticleLoadListTask articleLoadListTask = new ArticleLoadListTask();
    private final ArticleUpdateTitleTask articleUpdateTitleTask = new ArticleUpdateTitleTask();
    private final ArticleAddTask articleAddTask = new ArticleAddTask();
    private final ArticleDeleteTask articleDeleteTask = new ArticleDeleteTask();
    private final ArticleChangeIndexTask articleChangeIndexTask = new ArticleChangeIndexTask();
    
    /**
     * 記事ツリービュー
     */
    @FXML
    private TreeView<ArticleModel> articleTreeView;

    /**
     * コンストラクタ
     */
    public MainController() {
        setInstance();
        loadFXML();
    }

    /**
     * 初期化メソッド
     */
    private void loadFXML() {
        // ---------------------------------------------------
        // FXMLのロードと設定
        // ---------------------------------------------------
        FXMLLoader fxmlLoader = new FXMLLoader(TrickAdmin.class.getResource("fxml/main.fxml"));
        fxmlLoader.setRoot(this);
        // 自分自身をコントロールとして設定
        fxmlLoader.setController(this);
        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        try {
            // サイトチョイスボックスの初期化
            List<SiteMstEntity> accountList = DBManager.getSiteList(DBManager.getConn());
            accountChoiceBox.getItems().setAll(accountList);
            initSiteChoiceBox();
            
            // プログレスの初期化
            treeProgressIndicatorHBox.visibleProperty().bind(
                    new ArticleTreeProgressVisibleBinding(
                            articleLoadListTask,
                            articleUpdateTitleTask,
                            articleAddTask,
                            articleDeleteTask,
                            articleChangeIndexTask));
            
            // ステージ表示イベント
            TrickAdmin.getInstance().getStage().showingProperty().addListener(new ChangeListener<Boolean>() {

                @Override
                public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
                    // 表示された場合
                    if (t1) {
                        try {
                            // OAUTH情報がない場合
                            if (DBManager.getOauthEntity(DBManager.getConn()) == null) {
                                OAuthController controller = new OAuthController();
                                TrickAdmin.getInstance().showOAuthStage(controller);
                            }
                        } catch (IOException | SQLException ex) {
                            Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }

            });

        } catch (SQLException ex) {
            Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /**
     * サイト追加アクション
     * @throws IOException 
     */
    @FXML
    protected void addAccountAction() throws IOException {
        
        final AddSiteController controller = new AddSiteController();
        TrickAdmin.getInstance().showAddSiteStage(controller);
        
        controller.addButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
                try {
                    String siteId = controller.appIdTextField.getText();
                    String googleDriveKey = controller.googleDriveKeyTextField.getText();
                    
                    // DB登録
                    if (DBManager.getSiteEntity(DBManager.getConn(), siteId) == null) {
                        DBManager.insertOrUpdateSiteMst(DBManager.getConn(), siteId, googleDriveKey);

                        // アカウントチョイスボックスの初期化
                        List<SiteMstEntity> accountList = DBManager.getSiteList(DBManager.getConn());
                        accountChoiceBox.getItems().setAll(accountList);
                        
                    // 更新
                    }else {
                        DBManager.updateSiteEntity(DBManager.getConn(), siteMstEntity);
                    }
                    
                    // ステージを閉じる
                    TrickAdmin.getInstance().closeAddSiteStage();
                    
                } catch (SQLException ex) {
                    Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        
    }
    
    /**
     * サイトチョイスボックスの初期化
     * @throws java.sql.SQLException
     */
    private void initSiteChoiceBox() throws SQLException {
        
        accountChoiceBox.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> ov, Number oldValue, Number newValue) {
                try {
                    
                    if (newValue.intValue() >= 0) {
                        // サイトマスタの取得
                        siteMstEntity = accountChoiceBox.getItems().get(newValue.intValue());

                        // ツリービューの初期化
                        initArticleTree(siteMstEntity.getDomin());
                        
                    }
                    
                } catch (Exception ex) {
                    Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
    
    /**
     * ロードタスクの初期化
     */
    private void initArticleTree(String rootTitle) {
        ArticleModel rootModel = new ArticleModel();
        rootModel.setTitle(rootTitle);
        ArticleTreeItem rootItem = new ArticleTreeItem(rootModel);
        rootItem.setExpanded(true);
        articleTreeView.setRoot(rootItem);
    }
    
    /**
     * Get DriveTrick Instance
     *
     * @return
     */
    public static MainController getInstance() {
        return instance;
    }
    
    /**
     * インスタンスの設定
     */
    private void setInstance() {
        instance = this;
    }

    public ArticleLoadListTask getArticleLoadListTask() {
        return this.articleLoadListTask;
    }
    
    public ArticleUpdateTitleTask getArticleUpdateTitleTask() {
        return this.articleUpdateTitleTask;
    }
    
    public ArticleAddTask getArticleAddTask() {
        return this.articleAddTask;
    }
    
    public ArticleDeleteTask getArticleDeleteTask() {
        return this.articleDeleteTask;
    }
    
    public ArticleChangeIndexTask getArticleChangeIndexTask() {
        return this.articleChangeIndexTask;
    }
    
    public TreeView getArticleTreeView() {
        return this.articleTreeView;
    }
    
    public SiteMstEntity getSiteMstEntity() {
        return siteMstEntity;
    }

}
